const http = require('http')
const express = require('express')
const app = express()
const server = http.createServer(app)
const io = require('socket.io')(server)
// 监听端口服务器用 server对象
server.listen(3000, '127.0.0.1', () => console.log('http://localhost:3000'))
// 静态资源不受影响
app.use(express.static('./public'))

// 连接数据库
require('./db')
const model = require('./model/chat')

// 用户名称对应的socket对象
let sockets = {}

// 等待客户端连接
io.on('connection', socket => {
  let username = ''
  let ip = socket.conn.remoteAddress

  socket.broadcast.emit('message', {
    username: '【系统消息】',
    msg: ': 欢迎进入聊天室 --' + ip,
    at: new Date().toLocaleTimeString()
  })

  // 反馈给客户端连接成功
  socket.emit('open', 'ok')
  // 接受客户端发送过来的姓名，保存
  socket.on('name', uname => {
    username = uname
    // 不重复添加
    if (!sockets[uname]) {
      sockets[username] = socket
    }

    // 从数据库中获取数据回显示到界面中
    model.find({ $or: [{ touser: '' }, { touser: username }] }).sort({ updatedAt: -1 }).skip(0).limit(20).then(ret => {
      socket.emit('msgs', ret)
    })
  })

  // 接受客户端发送过来的数据
  socket.on('message', data => {
    data = data.trim()
    // 判断data中是否有@字符串 内容的消息，如果有，则表示它是一个私聊的消息
    let preg = /^@([^\s]+)\s+(.+)/
    let matchData = data.match(preg)
    if (matchData) { // 私聊
      // toUser它是一个socket对象
      let toUser = sockets[matchData[1]]
      toUser && model.create({
        username,
        // 存给谁发送的姓名
        touser: matchData[1],
        msg: matchData[2] || '笑脸',
        at: new Date().toLocaleTimeString()
      })

      toUser && toUser.send({
        username,
        msg: matchData[2] || '笑脸',
        at: new Date().toLocaleTimeString()
      })
      socket.send({
        username: '【我】',
        msg: matchData[2] || '笑脸',
        at: new Date().toLocaleTimeString()
      })
    } else {
      model.create({
        username,
        msg: data + ' -- ' + ip,
        at: new Date().toLocaleTimeString()
      })
      // 群聊
      socket.broadcast.emit('message', {
        username,
        msg: data + ' -- ' + ip,
        at: new Date().toLocaleTimeString()
      })
      socket.send({
        username: '【我】',
        msg: data,
        at: new Date().toLocaleTimeString()
      })
    }
  })

  // 离开事件处理
  socket.on('disconnect', () => {
    if (sockets[username]) {
      delete sockets[username]
    }
  });
});



